package org.dxy.infrastructure.persistent.db.mybatispuls.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.dxy.infrastructure.persistent.db.mybatispuls.po.query.SubstituteMaterialViewPo;
import org.dxy.infrastructure.persistent.db.mybatispuls.mapper.SubstituteMaterialViewMapper;
import org.dxy.infrastructure.persistent.db.mybatispuls.service.SubstituteMaterialViewService;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 替代料视图服务实现
 * @author dxy
 * @createTime 2025/9/13
 */
@Slf4j
@Service
public class SubstituteMaterialViewServiceImpl extends ServiceImpl<SubstituteMaterialViewMapper, SubstituteMaterialViewPo> implements SubstituteMaterialViewService {
    
    @Override
    public SubstituteMaterialViewPo getById(Long id) {
        log.debug("根据ID查询替代料详情, id={}", id);
        if (id == null) {
            return null;
        }
        return super.getById(id);
    }
    
    @Override
    public Page<SubstituteMaterialViewPo> list(Page<SubstituteMaterialViewPo> page, SubstituteMaterialViewPo query) {
        log.debug("分页查询替代料列表, page={}, query={}", page, query);
        
        LambdaQueryWrapper<SubstituteMaterialViewPo> wrapper = new LambdaQueryWrapper<>();
        
        // 构建查询条件
        if (StringUtils.hasText(query.getMainMaterialCode())) {
            wrapper.like(SubstituteMaterialViewPo::getMainMaterialCode, query.getMainMaterialCode());
        }
        if (StringUtils.hasText(query.getSubstituteMaterialCode())) {
            wrapper.like(SubstituteMaterialViewPo::getSubstituteMaterialCode, query.getSubstituteMaterialCode());
        }
        if (StringUtils.hasText(query.getStatus())) {
            wrapper.eq(SubstituteMaterialViewPo::getStatus, query.getStatus());
        }
        if (query.getMbomId() != null) {
            wrapper.eq(SubstituteMaterialViewPo::getMbomId, query.getMbomId());
        }
        if (query.getMbomItemId() != null) {
            wrapper.eq(SubstituteMaterialViewPo::getMbomItemId, query.getMbomItemId());
        }
        
        // 默认按创建时间倒序
        wrapper.orderByDesc(SubstituteMaterialViewPo::getCreatedTime);
        
        return page(page, wrapper);
    }
    
    @Override
    public List<SubstituteMaterialViewPo> getByMbomId(Long mbomId) {
        log.debug("根据MBOM ID查询替代料列表, mbomId={}", mbomId);
        if (mbomId == null) {
            return List.of();
        }
        return list(new LambdaQueryWrapper<SubstituteMaterialViewPo>()
                .eq(SubstituteMaterialViewPo::getMbomId, mbomId)
                .orderByAsc(SubstituteMaterialViewPo::getPriority)
                .orderByDesc(SubstituteMaterialViewPo::getCreatedTime));
    }
    
    @Override
    public List<SubstituteMaterialViewPo> getByMbomItemId(Long mbomItemId) {
        log.debug("根据MBOM项ID查询替代料列表, mbomItemId={}", mbomItemId);
        if (mbomItemId == null) {
            return List.of();
        }
        return list(new LambdaQueryWrapper<SubstituteMaterialViewPo>()
                .eq(SubstituteMaterialViewPo::getMbomItemId, mbomItemId)
                .orderByAsc(SubstituteMaterialViewPo::getPriority)
                .orderByDesc(SubstituteMaterialViewPo::getCreatedTime));
    }
    
    @Override
    public List<SubstituteMaterialViewPo> getByStatus(String status) {
        log.debug("根据状态查询替代料列表, status={}", status);
        if (!StringUtils.hasText(status)) {
            return List.of();
        }
        return list(new LambdaQueryWrapper<SubstituteMaterialViewPo>()
                .eq(SubstituteMaterialViewPo::getStatus, status)
                .orderByAsc(SubstituteMaterialViewPo::getPriority)
                .orderByDesc(SubstituteMaterialViewPo::getCreatedTime));
    }
    
    @Override
    public List<SubstituteMaterialViewPo> getByMainMaterialCode(String mainMaterialCode) {
        log.debug("根据主料编码查询替代料列表, mainMaterialCode={}", mainMaterialCode);
        if (!StringUtils.hasText(mainMaterialCode)) {
            return List.of();
        }
        return list(new LambdaQueryWrapper<SubstituteMaterialViewPo>()
                .eq(SubstituteMaterialViewPo::getMainMaterialCode, mainMaterialCode)
                .orderByAsc(SubstituteMaterialViewPo::getPriority)
                .orderByDesc(SubstituteMaterialViewPo::getCreatedTime));
    }
    
    @Override
    public List<SubstituteMaterialViewPo> getBySubstituteMaterialCode(String substituteMaterialCode) {
        log.debug("根据替代料编码查询替代料列表, substituteMaterialCode={}", substituteMaterialCode);
        if (!StringUtils.hasText(substituteMaterialCode)) {
            return List.of();
        }
        return list(new LambdaQueryWrapper<SubstituteMaterialViewPo>()
                .eq(SubstituteMaterialViewPo::getSubstituteMaterialCode, substituteMaterialCode)
                .orderByAsc(SubstituteMaterialViewPo::getPriority)
                .orderByDesc(SubstituteMaterialViewPo::getCreatedTime));
    }
    
    @Override
    public List<SubstituteMaterialViewPo> getAvailableSubstitutes(Long mbomItemId) {
        log.debug("查询可用的替代料, mbomItemId={}", mbomItemId);
        if (mbomItemId == null) {
            return List.of();
        }
        
        LocalDateTime now = LocalDateTime.now();
        
        return list(new LambdaQueryWrapper<SubstituteMaterialViewPo>()
                .eq(SubstituteMaterialViewPo::getMbomItemId, mbomItemId)
                .eq(SubstituteMaterialViewPo::getStatus, "ACTIVE")
                .and(wrapper -> wrapper
                    .isNull(SubstituteMaterialViewPo::getValidFrom)
                    .or()
                    .le(SubstituteMaterialViewPo::getValidFrom, now))
                .and(wrapper -> wrapper
                    .isNull(SubstituteMaterialViewPo::getValidTo)
                    .or()
                    .ge(SubstituteMaterialViewPo::getValidTo, now))
                .orderByAsc(SubstituteMaterialViewPo::getPriority)
                .orderByDesc(SubstituteMaterialViewPo::getCreatedTime));
    }
}